package com.lfl.filter;

import com.lfl.utils.FilterProperties;
import com.lfl.utils.RedisUtil;
import com.lfl.zuul.utils.ResponseResult;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.util.Objects;

@Component
public class PreFilter extends ZuulFilter {
    private final String TOKEN_PREFIX = "token_";

    private final String TOKEN_REFRESH = "refresh_";

    private final String TOKEN_LONG_REFRESH = "long_refresh_";

    @Override
    public String filterType() { // 过滤器类型
        return FilterConstants.PRE_TYPE;
    }

    @Override
    public int filterOrder() { //过滤器优先级
        return 1;
    }

    @Autowired
    private FilterProperties filterProp;

    @Autowired
    private ResponseResult result;

    @Override
    public Object run() throws ZuulException {
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletRequest request = ctx.getRequest();

        String token = request.getHeader("token");

        Boolean isLogined = false;

        String customerToken = null;
        if (Objects.nonNull(token)) {
            customerToken = RedisUtil.getStringValue(token);
        }
        if (Objects.isNull(customerToken)) {
            String[] tokenSplit = token.split(TOKEN_REFRESH);
            if (tokenSplit.length == 2) {
                String customerLongToken = RedisUtil.getStringValue(TOKEN_PREFIX + TOKEN_LONG_REFRESH + tokenSplit[1]);
                if (Objects.nonNull(customerLongToken)) {
                    // 用户10天内登录过，只是在过期时间内未发起新的请求，重新在redis中存入短期token
                    RedisUtil.setKey(TOKEN_PREFIX + TOKEN_REFRESH + tokenSplit[1], tokenSplit[1]);
                    RedisUtil.setKeyRefresh(TOKEN_PREFIX + TOKEN_REFRESH + tokenSplit[1]);
                    isLogined = true;
                }
            }
        } else {
            isLogined = true;
        }
        if (!isLogined) {
            // 未能成功校验
            ctx.setSendZuulResponse(false);
            ctx.setResponseStatusCode(400);
            ctx.setResponseBody("login failed");
        }
        return null;
    }

    @Override
    public boolean shouldFilter() {
        // 获取上下文
        RequestContext ctx = RequestContext.getCurrentContext();
        // 获取request
        HttpServletRequest req = ctx.getRequest();
        // 获取路径
        String requestURI = req.getRequestURI();
        // 判断白名单
        return !isAllowPath(requestURI);
    }

    private boolean isAllowPath(String requestURI) {
        // 定义一个标记
        boolean flag = false;
        // 遍历允许访问的路径
        for (String path : this.filterProp.getAllowPaths()) {
            // 然后判断是否是符合
            if (requestURI.startsWith(path)) {
                flag = true;
                break;
            }
        }
        return flag;
    }
}